package com.tanhua.gateway.filters;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Value("${gateway.excludedUrls}")
    private List<String> excludedUrls;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        判断请求头是否携带token
        ServerHttpRequest request = exchange.getRequest();

        String path = request.getURI().getPath();//    /user/login
        if(excludedUrls.contains(path)){
            return chain.filter(exchange);//放行
        }

//        excludedUrls是否包含当前请求的路基。如果包含直接放行

        String token = request.getHeaders().getFirst("Authorization");
        token = token.replace("Bearer ",""); //因为后台管理项目的这个参数会带着"Bearer "，这里需要去除
//        判断token是否合法
        boolean verifyToken = JwtUtils.verifyToken(token);
        if(verifyToken){
            return chain.filter(exchange);//放行
        }else{
//            返回：{"errCode":401,"errMessage":""用户未登录"}
            //6、如果token失效，构造返回，并指定相应状态401
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //return response.setComplete();
            //相应数据
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            //返回的错误数据   {errCode：401，message：xxxx}
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("errCode", 401);
            responseData.put("errMessage", "用户未登录");
            //将对象，转化为json字符串（已byte数组的形式提现）
            byte[] data = JSON.toJSONBytes(responseData);
            DataBuffer buffer = response.bufferFactory().wrap(data); //数据DatBuffer
            return response.writeWith(Mono.just(buffer));
        }
    }

    @Override
    public int getOrder() {
        return 0; // 值越小是越先执行
    }
}
